// std functions
#include <iostream>
#include <stdexcept>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <math.h>

// boost functions
#include <boost/program_options.hpp>

// my functions
#include <print_error.h>
#include <program_options_helper.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 6
#include <debug_func.h>
#include <blast_results.h>
#include "get_arg.h"
using std::string;
using std::cerr;
using std::cout;
using std::max;




// link with -lboost_filesystem-gcc -lboost_program_options-gcc
// program_options_helper.cpp
//-lboost_filesystem-gcc-d
//-L/usr/local/lib

using namespace program_options_helper;
namespace po = boost::program_options_lg;


//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{

	//
	// checked mandatory arguments
	//
	po::options_description mandatory_args("Mandatory Arguments");
	mandatory_args.add_options()
	("input_file,i",			po::value<string>(&args.file_input)
										->set_name("FILE"),
									"File containing alignment results.")
	("path,p", po::value<string>(&args.path)->set_name("PATH"),
						"Path for the resulting files. Must include the term "
						"[INDEX] which will contain the index of the file.");


	args.optional_args.add_options()
	("every,E", po::value<std::streamsize>(&args.every)->set_name("NUMBER")
							->default_value(200),
						"Number of desird sequences per file when there are large number "
						"of sequences.")
	("min_sequence_count,m", po::value<std::streamsize>(&args.min_sequence_count)->set_name("NUMBER")
							->default_value(1),
						"Minimum number of sequences per file when there are few sequences.")
	("min_file_count,M", po::value<std::streamsize>(&args.min_file_count)->set_name("NUMBER")
							->default_value(1),
						"Minimum number of resulting files when there are few sequences.");

	args.add_std_options();
	po::options_description all_args("");                              
	all_args
		.add(mandatory_args)
		.add(args.optional_args);

	// parse command line
	po::variables_map vm;
	po::store(po::command_line_parser(argc, argv).options(all_args).run(), vm);
	po::notify(vm);

	if (vm.count("version"))
	{
		print_version(	
						cerr, *argv, "1.1\n"
						"\tHistory: \n\n"
						"\tv 1.0\1"
						"30-07-2005\1"
						"Initial version\n"
						"\tv 1.1\1"
						"16-10-2005\1"
						"Added minimum_sequence_count etc. parameters to better control"
						"the number of files generated for small number of sequences.\n"
			);
		return false;
	}

	if (vm.count("help"))
	{
		string exe_description =
								"Splits sequence files in FASTA format.\n"
								"Puts N sequences per file where N is a number specified "
								"via the --every option.\n"
								"The resulting files have successive indices starting from 0.\n"
								"The indices are specified in the path using the [INDEX] "
								"placeholder. Thus /home/user/result[INDEX].fasta will "
								"give 'result0.fasta', 'result1.fasta' 'result2.fasta' etc.\n\n"
								"The programme tries to produce at least "
								"--min_file_count files by reducing the number of "
								"sequences per file below that specified in --every if "
								"necessary.\n"
								"However, if there are so few sequences that each file "
								"will contain fewer than --min_sequence_count then the "
								"number of resulting files is reduced.";

		print_usage(cerr, string(*argv), "--path PATH [OPTIONS] < SEQUENCES.FASTA",
							all_args, exe_description, 80);
		return false;
	}
	check_required_options(vm, mandatory_args);
	if (!args.every)
		throw std::runtime_error("The number of desired sequences per file specified in "
								 "--every must be greater than zero!");
	if (!args.min_sequence_count)
		throw std::runtime_error("The minimum number of sequences per file specified in "
								 "--min_sequence_count must be greater than zero!");
	if (!args.min_file_count)
		throw std::runtime_error("The number of files specified in --min_file_count "
									"must be greater than zero!");
	if (args.path.find("[INDEX]") == string::npos)
		throw std::runtime_error("The PATH specified in the --path option must include the "
									"term [INDEX]!");
	args.open_err_log();

	// this is so clear stupid that I am not even going to warn you
	if (args.min_sequence_count > args.every)
	{
		std_print_warning(args.CERR(), "The minimum sequence count (min_sequence_count)\n"
									   "is larger than the target sequence count (--every)\n"
									   "and will be ignored." );
		args.min_sequence_count = args.every;
	}

	return true;
}



